#include "stdafx.hpp"
#include "win32/MciDisc.h"

#ifdef __WXMSW__

CMciDisc::CMciDisc ( const wxString &rDevice ) : mTrackCount(0)
{
	using namespace boost;

	mDevice = rDevice;

	if ( mDevice == "cdaudio" )
	{
		SendString ( str ( format ( "open %1% shareable" ) % mDevice ) );
	}
	else
	{
		SendString ( str ( format ( "open %1% type cdaudio shareable") % mDevice ) ); 
	}
	ReadTrackCount();
	CreateTracks();
	SendString ( "close " + mDevice );
}

CMciDisc::~CMciDisc()
{
}

wxUint32 CMciDisc::GetTrackCount() const
{
	return mTrackCount;
}

unsigned long CMciDisc::GetStartFrame ( wxUint32 track ) const
{
	return mTracks[track].GetStartFrame();
}

unsigned long CMciDisc::GetFrames ( wxUint32 track ) const
{
	return mTracks[track].GetFrames();
}

void CMciDisc::ReadTrackCount()
{
	using namespace boost;
	using namespace std;

	istringstream i ( SendString ( str ( format 
		( "status %1% number of tracks") % mDevice ) ) );

	i >> mTrackCount;
}

void CMciDisc::CreateTracks()
{
	using namespace boost;

	const format len_frmt ( "status %1% length track %2%" );
	const format pos_frmt ( "status %1% position track %2%" );

	for ( wxUint32 track = 0; track < mTrackCount; ++track )
	{
		SendString ( str ( format ( "set %1% time format msf" ) % mDevice ) );

		const wxString track_pos ( SendString ( str ( format 
			( pos_frmt ) % mDevice % ( track + 1 ) ) ) );

		wxUint32 start_min = 0, start_sec = 0, start_frame = 0;

		sscanf ( ( const char* )track_pos.c_str(), "%02d:%02d:%02d", 
			&start_min, &start_sec, &start_frame );

		const wxString track_len ( SendString ( str ( format
			( len_frmt ) % mDevice % ( track + 1 ) ) ) );

		wxUint32 len_min = 0, len_sec = 0, len_frame = 0;

		sscanf ( ( const char * )track_len.c_str(), "%02d:%02d:%02d", &len_min, 
			&len_sec, &len_frame );

		mTracks.push_back ( Track ( ( 60 * CDiscHelper::GetFramesPerSecond() * 
			start_min + CDiscHelper::GetFramesPerSecond() * start_sec + start_frame ), 
			( 60 * CDiscHelper::GetFramesPerSecond() * len_min + 
			CDiscHelper::GetFramesPerSecond() * len_sec + len_frame + 1 ), track_len ) );
	}
}

const wxString CMciDisc::SendString ( const wxString &rCommand ) const
{
	wxLogDebug ( "MCI: %s", rCommand );

	wxString result;

	const wxInt32 max_len = 1024;
	const MCIERROR status = mciSendString ( ( LPCWSTR ) rCommand.c_str(), 
		wxStringBuffer ( result, max_len ), max_len, NULL );
	if ( status != S_OK )
	{
		mciGetErrorString ( status, wxStringBuffer ( result, max_len ), max_len );
		throw std::runtime_error ( ( const char * )result.c_str() );
	}
	return result;
}

#endif	// __WXMSW__
